You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
sched_ext_simple.ks (and other examples using extern kfunc declarations) compiled in KernelScript but produced eBPF C that failed to build. This branch fixes the three distinct problems found along the way.
1. Lower kfunc declarations into the IR
extern kfunc declarations were registered in the type checker and symbol table but never lowered into the IR, so the eBPF C backend never emitted extern ... __ksym; declarations for them — generated .ebpf.c called kfuncs like scx_bpf_dsq_insert with no declaration in scope.
Both kernel-provided extern kfuncs and locally-defined @kfunc prototypes are now represented as a new IRDeclKfuncDecl source declaration, emitted in source order from the IR. This replaces the ~kfunc_declarations / ~extern_declarations side-channel arguments that previously smuggled AST fragments past the IR into the backend.
2. Skip __ksym externs for standard BPF helpers
KernelScript uses extern for both kfuncs and BPF helpers, and shipped examples (extern_kfunc_demo.ks, include_demo.ks) declare helpers like bpf_ktime_get_ns with it. Emitting extern ... __ksym; for those clashed with libbpf's bpf_helpers.h, which already declares every helper.
A new Bpf_helpers module enumerates the standard helpers (mirroring libbpf's bpf_helper_defs.h); the backend skips the __ksym declaration for any extern naming one. Real kfuncs are unaffected.
3. Compile eBPF objects with -fno-builtin
struct_ops method names come from the kernel struct, so a sched_ext_ops scheduler must define an exit method. eBPF objects never link libc, but clang still recognises exit as a compiler builtin (void(int) noreturn) regardless of -target bpf — it compiled the fall-through body away to a zero-size section, and libbpf then rejected the object.
-fno-builtin is added to the generated Makefile's BPF_CFLAGS. eBPF C relies only on __builtin_* intrinsics (KernelScript emits __builtin_memcpy, never bare memcpy; struct-copy lowering uses the llvm.memcpy intrinsic) — none of which -fno-builtin affects.
Testing
Full suite: 85 test suites pass, 0 failures. New tests cover extern-kfunc IR codegen, the BPF-helper skip, and verbatim emission of builtin-named struct_ops methods.
sched_ext_simple now builds fully end-to-end (.ebpf.o, skeleton, userspace binary).
Verified every example's eBPF object builds with -fno-builtin.
Remaining blockers for sched_ext_simple on 7.0.0-15-generic**
on my environment (Linux 7.0.0-15-generic), sched_ext_simple still fails to compile and load. We need a few follow-ups to truly fulfill the "compiles" goal:
1. Blocking: Redundant extern declarations for kfuncs
The codegen still emits extern declarations for kfuncs that are already defined in vmlinux.h (e.g., scx_bpf_select_cpu_dfl, scx_bpf_dsq_insert). Because KernelScript currently uses placeholder types (like __u8*) that conflict with the real signatures in the kernel BTF, Clang throws a conflicting types error. We should skip emitting extern if the symbol is already provided by the BTF/vmlinux.h.
2. Blocking: API Deprecation (scx_bpf_consume)
In the current kernel (7.0+), scx_bpf_consume has been removed and replaced by scx_bpf_dsq_move_to_local. The example needs to be updated to the new API; otherwise, libbpf will fail at load time with extern ksym not found.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sched_ext_simple.ks(and other examples usingexternkfunc declarations) compiled in KernelScript but produced eBPF C that failed to build. This branch fixes the three distinct problems found along the way.1. Lower kfunc declarations into the IR
externkfunc declarations were registered in the type checker and symbol table but never lowered into the IR, so the eBPF C backend never emittedextern ... __ksym;declarations for them — generated.ebpf.ccalled kfuncs likescx_bpf_dsq_insertwith no declaration in scope.Both kernel-provided
externkfuncs and locally-defined@kfuncprototypes are now represented as a newIRDeclKfuncDeclsource declaration, emitted in source order from the IR. This replaces the~kfunc_declarations/~extern_declarationsside-channel arguments that previously smuggled AST fragments past the IR into the backend.2. Skip
__ksymexterns for standard BPF helpersKernelScript uses
externfor both kfuncs and BPF helpers, and shipped examples (extern_kfunc_demo.ks,include_demo.ks) declare helpers likebpf_ktime_get_nswith it. Emittingextern ... __ksym;for those clashed with libbpf'sbpf_helpers.h, which already declares every helper.A new
Bpf_helpersmodule enumerates the standard helpers (mirroring libbpf'sbpf_helper_defs.h); the backend skips the__ksymdeclaration for anyexternnaming one. Real kfuncs are unaffected.3. Compile eBPF objects with
-fno-builtinstruct_ops method names come from the kernel struct, so a
sched_ext_opsscheduler must define anexitmethod. eBPF objects never link libc, but clang still recognisesexitas a compiler builtin (void(int) noreturn) regardless of-target bpf— it compiled the fall-through body away to a zero-size section, and libbpf then rejected the object.-fno-builtinis added to the generated Makefile'sBPF_CFLAGS. eBPF C relies only on__builtin_*intrinsics (KernelScript emits__builtin_memcpy, never barememcpy; struct-copy lowering uses thellvm.memcpyintrinsic) — none of which-fno-builtinaffects.Testing
sched_ext_simplenow builds fully end-to-end (.ebpf.o, skeleton, userspace binary).-fno-builtin.🤖 Generated with Claude Code